package com.aliyun.heiyu.powermaster.server.rotary.service.impl;

import com.aliyun.heiyu.common.util.DateUtil;
import com.aliyun.heiyu.powermaster.server.annotation.Transactional;
import com.aliyun.heiyu.powermaster.server.rotary.contants.ModbusOrderContant;
import com.aliyun.heiyu.powermaster.server.rotary.dao.IpcDAO;
import com.aliyun.heiyu.powermaster.server.rotary.dao.PduDAO;
import com.aliyun.heiyu.powermaster.server.rotary.dao.impl.IpcDAOImpl;
import com.aliyun.heiyu.powermaster.server.rotary.dao.impl.PduDAOImpl;
import com.aliyun.heiyu.powermaster.server.rotary.object.transit.ResTem;
import com.aliyun.heiyu.powermaster.server.rotary.object.transit.TemData;
import com.aliyun.heiyu.powermaster.server.rotary.service.IpcService;
import com.aliyun.heiyu.powermaster.server.rotary.service.PDUService;
import com.aliyun.heiyu.powermaster.server.rotary.task.PduDataTask;
import com.aliyun.heiyu.powermaster.server.rotary.utils.IpcDataUtil;
import com.aliyun.heiyu.powermaster.server.rotary.utils.JdbcUtil;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @Description pdu服务器实现
 * @Author shun.zhang
 * @Date 2020/9/11 16:33
 **/
public class PduServiceImpl implements PDUService {
    private static Logger logger = LoggerFactory.getLogger(PduServiceImpl.class);
    private IpcDAO ipcDAO;
    private PduDAO pduDAO;
    private IpcService ipcService;

    public PduServiceImpl() {
        ipcService = new IpcServiceImpl();
        pduDAO = new PduDAOImpl();
        ipcDAO = new IpcDAOImpl();
    }

    /**
     * 查询工控机信息
     *
     * @return
     */
    public Map<String, String> queryIpc() {
        return ipcDAO.queryIpc();
    }

    /**
     * 获取并保存pdu的动态数据
     *
     * @param
     * @return void
     **/
    @Transactional
    public void saveDataByPDU() {
        /**获取工控机信息*/
        Map<String, String> map = queryIpc();
        if (null == map) {
            return;
        }
        /**1.获取所有在使用的pdu*/
        List<Map<String, String>> pdus = pduDAO.getPdus();
        if (CollectionUtils.isEmpty(pdus)) {
            return;
        }
        for (Map<String, String> pdu : pdus) {
            if (!pdu.containsKey("device_id")) {
                continue;
            }
            StringBuffer sbu = new StringBuffer();
            /**2.读取数据*/
            String requestModbus = IpcDataUtil.potData("modbus", 9, ModbusOrderContant.READ, 1, 80);
            sbu.append("http://")
                .append(map.get("ip"))
                .append(":")
                .append(map.get("port"))
                .append("/getValue");
            logger.info("获取pdu动态数据请求路径：+"+sbu.toString()+" 请求参数："+ requestModbus);
            ResTem resTem = ipcService.sendOrderToIpc(sbu.toString(), requestModbus);
            if (null == resTem || null == resTem.getData()) {
                return;
            }
            logger.info("获取动环pdu数据："+resTem.getData());
            /**3.保存*/
            //保存pdu基础信息
            boolean device_id = savePduBase(resTem, pdu.get("device_id"));
            //保存支路电流
            boolean pduElectric = savePduElectric(resTem, pdu.get("device_id"));
            //保存支路功率
            boolean pduPower = savePduPower(resTem, pdu.get("device_id"));
            //保存电池信息
            saveBatteryBase(resTem);
            if (pduElectric && pduPower && device_id) {
                logger.info("保存pdu的支路电流丶基础信息及支路功率成功");
            }
        }
    }

    /**
     * 保存pdu功率
     *
     * @param resTem
     * @param deviceId
     * @return
     */
    private boolean savePduPower(ResTem resTem, String deviceId) {
        TemData temData = IpcDataUtil.getData(resTem.getData());
        Map<Integer, Double> data = temData.getValue();
        if (data.isEmpty() || data.size() < 48) {
            return false;
        }
        //获取功率
        //分离出第24到48位
        Map<Integer, Double> resultMap = getValue(data, 25, 48);
        logger.info("动环获取pdu功率:"+resultMap);
        if (null == resultMap) {
            return false;
        }
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO device_pdu_branch_power (guid,device_id,branch_number,branch_power,create_time,del) VALUES ");
        //25-48 支路功率
        Object[] obj = new Object[resultMap.keySet().size()*6];
        int count = 0;
        for (Integer key : resultMap.keySet()) {
            sql.append("(?,?,?,?,?,?),");
            obj[count++] = deviceId;
            obj[count++] = deviceId;
            obj[count++] = key;
            obj[count++] = resultMap.get(key);
            obj[count++] = DateUtil.dateToString(PduDataTask.pduDate);
            obj[count++] = 1;
        }
        String resultSql = sql.toString().substring(0, sql.length() -1);
        //保存数据
        JdbcUtil.insert(resultSql, obj);
        return true;
    }

    /**
     * 保存pdu电池信息
     *
     * @param resTem
     * @param
     * @return
     */
    private boolean saveBatteryBase(ResTem resTem) {
        TemData temData = IpcDataUtil.getData(resTem.getData());
        Map<Integer, Double> data = temData.getValue();
        if (data.isEmpty() || data.size() < 70) {
            return false;
        }
        //分离出第49到57位
        Map<Integer, Double> resultMap = getValue(data, 58, 70);
        if (null == resultMap) {
            return false;
        }
        logger.info("动环电池信息:"+resultMap);
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO support_device_info");
        sql.append(" (smoke_alert, current_meter_type, branches, support_device_1_version, support_device_2_version, support_device_3_version, support_device_4_version, support_device_5_version, support_device_6_version, device_type_sign, meter_version, battery_voltage, M0_hardware_version)");
        sql.append(" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)");
        //49-57 pdu基础动态信息
        Object[] obj = new Object[13];
        obj[0] = resultMap.get(1);
        obj[1] = resultMap.get(2);
        obj[2] = resultMap.get(3);
        obj[3] = resultMap.get(4);
        obj[4] = resultMap.get(5);
        obj[5] = resultMap.get(6);
        obj[6] = resultMap.get(7);
        obj[7] = resultMap.get(8);
        obj[8] = resultMap.get(9);
        obj[9] = resultMap.get(10);
        obj[10] = resultMap.get(11);
        obj[11] = resultMap.get(12);
        obj[12] = resultMap.get(13);
        //保存数据
        JdbcUtil.insert(sql.toString(), obj);
        return true;
    }

    /**
     * 保存pdu基础信息
     *
     * @param resTem
     * @param deviceId
     * @return
     */
    private boolean savePduBase(ResTem resTem, String deviceId) {
        TemData temData = IpcDataUtil.getData(resTem.getData());
        Map<Integer, Double> data = temData.getValue();
        if (data.isEmpty() || data.size() < 48) {
            return false;
        }
        //分离出第49到57位
        Map<Integer, Double> resultMap = getValue(data, 49, 57);
        if (null == resultMap) {
            return false;
        }
        logger.info("动环获取pdu基础信息:"+ resultMap);
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO device_pdu_base");
        sql.append(" (guid, device_id, frequency, electric_current, voltage, active_power, no_work_power, inspecting_power, power_factor, active_energy, no_work_energy, create_time, update_time, del)");
        sql.append(" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,1)");
        //49-57 pdu基础动态信息
        Object[] obj = new Object[13];
        obj[0] = deviceId;
        obj[1] = deviceId;
        obj[2] = resultMap.get(1);
        obj[3] = resultMap.get(2);
        obj[4] = resultMap.get(3);
        obj[5] = resultMap.get(4);
        obj[6] = resultMap.get(5);
        obj[7] = resultMap.get(6);
        obj[8] = resultMap.get(7);
        obj[9] = resultMap.get(8);
        obj[10] = resultMap.get(9);
        obj[11] = PduDataTask.pduDate;
        obj[12] = PduDataTask.pduDate;
        //保存数据
        JdbcUtil.insert(sql.toString(), obj);
        return true;
    }
    /**
     * 保存pdu电流
     *
     * @param resTem
     * @param deviceId
     * @return
     */
    private boolean savePduElectric(ResTem resTem, String deviceId) {
        TemData temData = IpcDataUtil.getData(resTem.getData());
        Map<Integer, Double> data = temData.getValue();
        //分离出第1到24位
        Map<Integer, Double> resultMap = getValue(data, 1, 24);
        if (null == resultMap) {
            return false;
        }
        logger.info("动环获取pdu电流:"+resultMap);
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO device_pdu_branch_electric (guid,device_id,branch_number,branch_electric,create_time,del) VALUES ");
        //25-28 支路功率
        int count = 0;
        Object[] obj = new Object[resultMap.keySet().size()*6];
        for (Integer key : resultMap.keySet()) {
            sql.append("(?,?,?,?,?,?),");
            obj[count++] = deviceId;
            obj[count++] = deviceId;
            obj[count++] = key;
            obj[count++] = resultMap.get(key);
            obj[count++] = DateUtil.dateToString(PduDataTask.pduDate);
            obj[count++] = 1;
        }
        //整理values数据
        String resultSql = sql.toString().substring(0, sql.length() -1);
        //保存数据
        JdbcUtil.insert(resultSql, obj);
        return true;
    }

    /**
     * 分离出第多少位到多少位的数据
     *
     * @param map
     * @param start
     * @param end
     * @return
     */
    private Map<Integer, Double> getValue(Map<Integer, Double> map, int start, int end) {
        int count = 1;
        if (start < 1 || end < 1 || end < start) {
            return null;
        }
        Map<Integer, Double> result = new HashMap<>();
        for (int i = start; i <= end; i++) {
            result.put(count++, map.get(i + 1));
        }
        return result;
    }
}
